home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************/
- /* */
- /* GNAT COMPILER COMPONENTS */
- /* */
- /* A - I N I T */
- /* */
- /* $Revision: 1.6 $ */
- /* */
- /* C Implementation File */
- /* */
- /* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. */
- /* */
- /* GNAT is free software; you can redistribute it and/or modify it under */
- /* terms of the GNU General Public License as published by the Free Soft- */
- /* ware Foundation; either version 2, or (at your option) any later ver- */
- /* sion. GNAT is distributed in the hope that it will be useful, but WITH- */
- /* OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY */
- /* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License */
- /* for more details. You should have received a copy of the GNU General */
- /* Public License distributed with GNAT; see file COPYING. If not, write */
- /* to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, */
- /* MA 02111-1307, USA. */
- /* */
- /* As a special exception, if you link this file with other files to */
- /* produce an executable, this file does not by itself cause the resulting */
- /* executable to be covered by the GNU General Public License. This except- */
- /* ion does not however invalidate any other reasons why the executable */
- /* file might be covered by the GNU Public License. */
- /* */
- /* GNAT was originally developed by the GNAT team at New York University. */
- /* It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). */
- /* */
- /****************************************************************************/
-
- /* This routine is called right at the start of execution of an Ada program
- (the call is generated by the binder). The standard routine does nothing
- at all, the intention is that this be replaced by system specific code
- where initialization is required. */
-
- #if (!defined (MSDOS) && !defined (sgi))
- /* This routine is called right at the start of execution of an Ada program
- (the call is generated by the binder). The standard routine does nothing
- at all, the intention is that this be replaced by system specific code
- where initialization is required. */
-
- __gnat_initialize()
- {
- }
- #endif
-
- #if defined (MSDOS)
- #include <stdio.h>
-
- /* This is DOS specific. It does nothing unless run from an
- environment that creates a gw-gnat.$$$ file. If that file is present,
- it forces all program output to the console. This allows the debugger
- to be run sending output to a file, but the program output still goes
- to the console. */
-
- __gnat_initialize()
- {
- if (access("gw-gnat.$$$", 0) == 0)
- freopen("CON", "w", stdout);
- }
- #endif
-
- #if defined (sgi)
- /* This is SGI specific */
-
- #include <signal.h>
- #include <sys/siginfo.h>
- #include <sys/ucontext.h>
- #include <sys/types.h>
-
- /* #include "a-raise.h" */
-
- #define SIGNAL_STACK_SIZE 4096
- #define SIGNAL_STACK_ALIGNMENT 64
- #define NULL 0
-
- extern char constraint_error asm ("constraint_error");
- extern char numeric_error asm ("numeric_error");
- extern char program_error asm ("program_error");
- extern char storage_error asm ("storage_error");
- extern char tasking_error asm ("tasking_error");
- extern char _abort_signal asm ("_abort_signal");
-
- extern void system__task_specific_data__set_gnat_exception (void* e);
- extern char *system__task_specific_data__get_gnat_exception ();
- extern int *system__task_specific_data__get_jmpbuf_address ();
- extern void *system__task_specific_data__get_exc_stack_addr ();
- extern void __gnat_reraise ();
-
- char* signal_stack; /* Alternate signal stack */
-
- static void __gnat_error_handler (int sig, int code, struct sigcontext *sc)
- {
-
- char* exception;
- void* exc_stack = system__task_specific_data__get_exc_stack_addr ();
-
- if (sig == SIGSEGV) {
-
- if (code == SEGV_MAPERR) {
- /* Assume reference to unmapped pages is a bad pointer dereference
- and map it to constraint_error */
- exception = &constraint_error;
-
- } else {
- /* Otherwise we: are referencing a mapped page that is protected, or
- have reached our process's stack limit (see setrlimit(2)).
- In both cases, raise Storage_Error */
- exception = &storage_error;
- }
-
- } else if (sig == SIGBUS) {
- /* Map all bus errors to constraint_error */
- exception = &constraint_error;
-
- } else if (sig == SIGFPE) {
- /* Map all fpe errors to constraint_error */
- exception = &constraint_error;
-
- } else {
- /* Everything else is a program_error */
- exception = &program_error;
- }
-
- system__task_specific_data__set_gnat_exception (exception);
-
- /* Overwrite the signal context's saved PC with the address of
- the gnat_reraise routine, so the return from this handler
- will resume execution at the raise point. */
-
- /* sc->sc_pc = (__uint64_t) ((int)__gnat_reraise + 0xC); */
- sc->sc_pc = (__uint64_t) ((int)__gnat_reraise);
-
- /* Overwrite the saved SP value with the thread's special exception
- stack pointer so the exception propagation code will run on
- that stack. This is necessary if we are raising Storage_Error
- resulting from a task stack overrun. */
-
- sc->sc_regs [CTX_SP] = (__uint64_t) ((int)exc_stack);
-
- /* Set T9 to the address of __gnat_reraise so the GP adjustment in
- the function prologue is correct */
-
- sc->sc_regs [CTX_T9] = (__uint64_t) ((int)__gnat_reraise);
-
- /* Set the first argument register (a0/$4) to -1 so that gnat_reraise
- will call abort_defer prior to propagating the exception. */
-
- sc->sc_regs [CTX_A0] = -1;
-
- }
-
-
-
- static __gnat_install_handler ()
- {
-
- stack_t ss;
- struct sigaction act;
-
- /* Setup alternate signal stack */
-
- signal_stack = (char*) memalign (SIGNAL_STACK_ALIGNMENT, SIGNAL_STACK_SIZE);
-
- ss.ss_sp = &signal_stack[SIGNAL_STACK_SIZE];
- ss.ss_size = SIGNAL_STACK_SIZE;
- ss.ss_flags = 0;
-
- (void) sigaltstack (&ss, NULL);
-
- /* Setup signal handler to map synchronous signals to appropriate
- exceptions. Make sure that the handler isn't interrupted by another
- signal that might cause a scheduling event! */
-
- act.sa_handler = __gnat_error_handler;
- act.sa_flags = SA_ONSTACK + SA_NODEFER;
- (void) sigfillset (&act.sa_mask);
-
- (void) sigaction (SIGILL, &act, NULL);
- (void) sigaction (SIGABRT, &act, NULL);
- (void) sigaction (SIGFPE, &act, NULL);
- (void) sigaction (SIGSEGV, &act, NULL);
- (void) sigaction (SIGBUS, &act, NULL);
-
- }
- __gnat_initialize()
- {
- __gnat_install_handler();
- }
-
- #endif
-